//main htb class
//deb kanti
package fctu.simulator;

//import java.awt.Dimension;
import com.hitechbangla.fctu.base.GameScene;
import com.hitechbangla.fctu.base.MeasureHelper;
import com.hitechbangla.fctu.base.PressedButtonEnum;
import com.hitechbangla.fctu.base.aircraft.Aircraft;
import com.hitechbangla.fctu.base.aircraft.DragAircraft;
//import com.hitechbangla.fctu.base.aircraft.DragAircraft;
import com.hitechbangla.fctu.base.aircraft.IFFOptionSelection;
import com.hitechbangla.fctu.base.base.Base;
import com.hitechbangla.fctu.base.base.Gbad;
import com.hitechbangla.fctu.base.base.Kpi;
import com.hitechbangla.fctu.base.map.FCTUMap;
import com.hitechbangla.fctu.base.map.WholeMap;
import com.hitechbangla.fctu.base.radar.AutoLock;
import com.hitechbangla.fctu.base.radar.AutoLockGround;
import com.hitechbangla.fctu.base.radar.Radar;
import com.hitechbangla.fctu.base.radar.RadarACInfoSelection;
import com.hitechbangla.fctu.base.weather.RandomCloud;
import com.hitechbangla.fctu.drawingTools.DrawHelper;
import com.hitechbangla.fctu.drawingTools.DrawString;
import com.hitechbangla.fctu.form.AddAircraft;
import com.hitechbangla.fctu.form.AddBase;
import com.hitechbangla.fctu.form.AddCloud;
import com.hitechbangla.fctu.form.AddECM;
import com.hitechbangla.fctu.form.AddEPM;
import com.hitechbangla.fctu.form.AddGBAD;
//import com.hitechbangla.fctu.form.AddMap;
import com.hitechbangla.fctu.form.AddRadar;
import com.hitechbangla.fctu.form.Addcom;
import com.hitechbangla.fctu.form.Addkpi;
import com.hitechbangla.fctu.form.AircraftTools;
import com.hitechbangla.fctu.form.CGI;
import com.hitechbangla.fctu.form.CommandAircraftNew;
import com.hitechbangla.fctu.form.Create;
import com.hitechbangla.fctu.form.CreateForm;
import com.hitechbangla.fctu.form.Gamecontrol;
import com.hitechbangla.fctu.form.GeometricFigure;
import com.hitechbangla.fctu.form.RadarTools;
import com.hitechbangla.fctu.form.Remove;
import com.hitechbangla.fctu.form.ShowTalkingStatus;
import com.hitechbangla.fctu.form.Utility;
import com.hitechbangla.fctu.form.Voicechat;
import com.hitechbangla.fctu.utility.GeneralUtil;
import com.hitechbangla.fctu.utility.RecordedGame;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.AffineTransform;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

//rabbi
import com.hitechbangla.fctu.utility.connection.FCTUClient;
import com.hitechbangla.fctu.utility.connection.GetClientsConnection;
import java.awt.event.InputEvent;
import java.awt.event.KeyListener;
import java.io.Serializable;
import java.util.HashMap;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.MapMarkerDot;

import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.util.Timer;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.openstreetmap.gui.jmapviewer.OsmMercator;
import org.openstreetmap.gui.jmapviewer.tilesources.OfflineOsmTileSource;

import javax.swing.JInternalFrame;

import org.multichat.client.ChatClient;

/**
 *
 * @author Hi-techbangla_2
 */
//public class HTB_MAIN extends JPanel implements ActionListener, Serializable 
public class HTB_MAIN extends JMapViewer implements ActionListener, Serializable {

    //ChatClient chatClient;//=new ChatClient();
    
    String servername = "localhost";
    static int vPressed=0;
    // if Network is connected
    public boolean isNetworkConnected = false;
    // if it is the game starter client
    public boolean isGameStarter = false;
    // if gamestarter then push values with FCTUClient
    public FCTUClient fctuClient = null;
    // if not a gamestarter then push values with GetClientsConnection
    public GetClientsConnection getClientConnection = null;
    public static HashMap<Integer, Integer> zoomMap;
    float lookAtX_NM, lookAtY_NM = 0;
    int RECT_SIZE = 10;
    //added for map
    //-- map 
    WholeMap map;
    private List<FCTUMap> worldMap;
    //end adding for map
    public String traineeName;
    public boolean flagDrawRadar = false;
    //CODE ADDED BY SAIFUL ABU
    public PressedButtonEnum lastPressedButton = PressedButtonEnum.NONE;
    //CODE ADDED END
    //these varialbes will handle drag effect
    MeasureHelper measureHelper;
    DrawString drawString = new DrawString();
    ShowTalkingStatus showTalkingStatus = new ShowTalkingStatus();
            
            
    public static double translate_x = 0, translate_y = 0;
    static int screen_height, screen_width;
    static JMenuBar menubar;
    static JMenu menu1, menu2, menu3;
    static JCheckBoxMenuItem aircraft, radarToolsMenu, create, utility, geofigure, cgi, gamecontrol, aircraftTools, voice;
    static JMenuItem  saveGS, loadGS, exit;
    //rabbi
    static JMenuItem openConnection;
    static JMenuItem lookupConnection;
    //rabbi end
    int flag = 0;
    int measureButtonClick = 0;
    int mousepressclik = 0;
    int mousemeasuretwo = 0;
    Point2D point;
    int clickCount = 0;
    double distance;
    //added for mouse position showing
    //final AlsXYMouseLabelComponent alsXYMouseLabel = new AlsXYMouseLabelComponent();
    final int NUM_PTS = 3;
    int xpos[] = new int[NUM_PTS];
    int ypos[] = new int[NUM_PTS];
    int arrind = 0;
    
    JInternalFrame myframe = null;
    // HTB_MAIN htbParent = new HTB_MAIN();
    /*
     zoom handle
     */
    AircraftTools frameAircraftTools;
    //frameAircraftTools = new AircraftTools(this);
    Addcom ob = new Addcom(this);
    RadarTools radarTools = new RadarTools(this);
    //Remove rm = new Remove();
    Create cr = new Create();
    Voicechat vc = new Voicechat();
    Utility ut = new Utility(this);
    CGI cgiForm;
    GeometricFigure fig = new GeometricFigure();
    public Gamecontrol frameGameControl;
    //static float current_zoom_level = 6; //initially zoom level = 64 nm
    static int current_zoom_level = 6;
    //static float current_zoom_level;
    public static float one_nm_equivalent_pixel;
    public static float one_px_equivalent_naut;
    
    //private float min_zoom = 5;
    //private float max_zoom = 15;
    //private float min_zoom = 1;
    private int min_zoom = 1;
    //private float max_zoom = 34;
    private int max_zoom = 34;
    public AutoLock autoLock;
    //static int translate_x = 0;
    //static int translate_y = 0;
    /**
     * @param args the command line arguments
     */
    //used to push and pop
    static AffineTransform affineTransform;
    //Game Scene
    public static GameScene gameScene;
    public boolean gameStarted = false;
    
    public static RadarACInfoSelection radarACInfoSelection;
    public static IFFOptionSelection iFFOptionSelection;
    
    private RecordedGame recordedGame;
    public static int currentZoom;
    private List<AutoLock> listAutoLock = new ArrayList<>();
    private List<AutoLockGround> listAutoLockGround = new ArrayList<>();
    
    public void setZoomMap(){
        zoomMap = new HashMap<Integer, Integer>();
        int zoomLevel = 34; //max zoom level
        int visibleNauticalMileWidth = 16; //maximum zoom is 16 nm
        float zoomIncrease = (float) .25;
        for (; zoomLevel > 0; zoomLevel--) {
            zoomMap.put(zoomLevel, visibleNauticalMileWidth);
            visibleNauticalMileWidth = (int) (visibleNauticalMileWidth + visibleNauticalMileWidth * zoomIncrease);
        }//end for
    }

    public HTB_MAIN(JInternalFrame htb) throws FileNotFoundException, IOException, ClassNotFoundException 
    {
        //added by saiful abu
        //fixing zoom
        this.myframe=htb;
        setZoomMap();
        
        //chatClient=new ChatClient();
        
        this.setZoomContolsVisible(false);
        this.setTileSource(new OfflineOsmTileSource("file:///D:/tiles/",3,14));
        gameScene = new GameScene();
        gameScene.HTBParent = this;
	frameAircraftTools = new AircraftTools(this);
	frameGameControl = new Gamecontrol(this);
        measureHelper = new MeasureHelper();
        
	//-- reading map data
	FileInputStream fin = new FileInputStream("src\\resources\\mapType.object");
	ObjectInputStream ois = new ObjectInputStream(fin);
	worldMap = (List<FCTUMap>) ois.readObject();
	ois.close();
	// end of map data

//	menubar = new JMenuBar();
//	menubar.setSize(30, 1000);
//	menubar = new JMenuBar();
//	menu1 = new JMenu("File");
//	menu2 = new JMenu("View");
//	menu3 = new JMenu("Help");
//
//	aircraft = new JCheckBoxMenuItem("Add");
//	aircraft.addActionListener(this);
//
//	radarToolsMenu = new JCheckBoxMenuItem("Radar Tools");
//	radarToolsMenu.addActionListener(this);
//
//	create = new JCheckBoxMenuItem("Create");
//	create.addActionListener(this);
//        
//        cgi = new JCheckBoxMenuItem("CGI");
//        cgi.addActionListener(this);
//
//	utility = new JCheckBoxMenuItem("Utility");
//	utility.addActionListener(this);
//
//	geofigure = new JCheckBoxMenuItem("Geometric Figure");
//	geofigure.addActionListener(this);
//
//	gamecontrol = new JCheckBoxMenuItem("Game Control");
//	gamecontrol.addActionListener(this);
//
//	aircraftTools = new JCheckBoxMenuItem("Aircraft Tools");
//	aircraftTools.addActionListener(this);
//
//	exit = new JMenuItem("Exit");
//	exit.addActionListener(this);
//
//        loadGS = new JMenuItem("Load Game");
//        loadGS.addActionListener(this);
//        
//        saveGS = new JMenuItem("Save Game");
//        saveGS.addActionListener(this);
//        
//	openConnection = new JMenuItem("Open Connection");
//	openConnection.addActionListener(this);
//
//	lookupConnection = new JMenuItem("Connect to a Game");
//	lookupConnection.addActionListener(this);
//
//	voice = new JCheckBoxMenuItem("Voice");
//	voice.addActionListener(this);
//
//
//	menubar.add(menu1);
//	menubar.add(menu2);
//	menubar.add(menu3);
//
//        menu1.add(loadGS);
//        menu1.add(saveGS);
//        menu1.add(openConnection);
//	menu1.add(lookupConnection);
//	menu1.add(exit);
//	
//
//	menu2.add(create);
//	menu2.add(aircraft);
//	menu2.add(radarToolsMenu);
//	menu2.add(aircraftTools);
//	menu2.add(utility);
//        menu2.add(cgi);
//	menu2.add(gamecontrol);
//	menu2.add(voice);
//	//menu2.add(geofigure);
//
//
//
//	frame = new JFrame("Java 2D Skeleton");
//
//	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//	frame.setUndecorated(true);

	//-- frame should be made full screen here
	//add panel
	CustomMouseListener mouseListener = new CustomMouseListener();
	//CustomKeyListener keyListener = new CustomKeyListener();
	CustomWheelListener wheelListener = new CustomWheelListener();
	//frame.addMouseListener(mouseListener);
	//frame.addMouseMotionListener(mouseListener);

	this.addMouseListener(mouseListener);
	this.addMouseMotionListener(mouseListener);
	this.addMouseWheelListener(wheelListener);
        //this.addKeyListener(keyListener);
	//myframe.addKeyListener(keyListener);

         this.addKeyListener(new KeyListener() 
         {
             CommandAircraftNew commandAircraftNew = new CommandAircraftNew(gameScene);
             @Override
            public void keyPressed(KeyEvent e) 
            { 
                switch(e.getKeyCode())
                {
                    case KeyEvent.VK_F7 :
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run()
                            {
                                commandAircraftNew.setVisible(true);
                            }
                        });
                    break;
                    case KeyEvent.VK_V :
                        JOptionPane.showMessageDialog(null, "v pressed");
                        vc.startTalking();
                        vPressed = (vPressed == 0) ? 1 : 0;
                        repaint();
                        break;
                        
                }
                
                
            }

            @Override
            public void keyTyped(KeyEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            @Override
            public void keyReleased(KeyEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            
        });
        this.setFocusable(true);

	//frame.setJMenuBar(menubar);

	////System.out.println("menubar size" + menubar.getSize());
	//screen_width = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
	//screen_height = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height;
	Toolkit tk = Toolkit.getDefaultToolkit();
	int xSize = ((int) tk.getScreenSize().getWidth());
	int ySize = ((int) tk.getScreenSize().getHeight());
	screen_width = xSize;
	screen_height = ySize;
	//frame.setSize( java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width,  java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width);
	//frame.setSize(xSize, ySize);
	//frame.add(this);
        myframe.add(this);

	//screen_width = this.getWidth();
	//screen_height = this.getHeight();
	//this.setSize(xSize, ySize);
	float jpanelWidth = this.getWidth();
	int jpanelHeight = this.getHeight();


	////System.out.println("Screen width : " + screen_width + " jpanel width : " + jpanelWidth);
	//translate_x = (float) (screen_width / 2.0);
	//translate_y = -(float) (screen_height / 2.0);

	//frame.setBounds(, , , );
	// frame.setSize(screen_width, screen_height);

	radarACInfoSelection = new RadarACInfoSelection();
	iFFOptionSelection = new IFFOptionSelection();
    }

    public void init_canvas(Graphics2D g) {
	g.setColor(Color.BLACK);
	g.fillRect(0, 0, getWidth(), getHeight());
	super.paint(g);
	/*
	 //draw whit line
        
	 g.setColor(Color.gray);
	 g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
	 g.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
        
	 //end of draw white line
	 */
	//draw cross hair
	g.setColor(Color.YELLOW);
	int crossSize = 5;
	int hairSize = 3;
	Stroke s = g.getStroke();
	g.setStroke(new BasicStroke(3));
	//first hair on x axis lower part
	g.drawLine(((getWidth() / 2) - crossSize - hairSize), (getHeight() / 2), ((getWidth() / 2) - crossSize), (getHeight() / 2));
	//second har on x axis uppper part
	g.drawLine(((getWidth() / 2) + crossSize), (getHeight() / 2), ((getWidth() / 2) + crossSize + hairSize), (getHeight() / 2));

	//third hair on y axis upper part
	g.drawLine((getWidth() / 2),
		((getHeight() / 2) - crossSize - hairSize),
		//(getHeight() / 2),
		(getWidth() / 2),
		((getHeight() / 2) - crossSize));
	//fourth hair on y axis
	g.drawLine((getWidth() / 2), ((getHeight() / 2) + crossSize), (getWidth() / 2), ((getHeight() / 2) + crossSize + hairSize));
	g.setStroke(s);
	//end of drawing cross hair

	g.translate(translate_x, translate_y);
	g.scale(1, -1);
	//Dimension d = getSize();
	//float width = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
	//float height = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height
	//g.translate((screen_width / 2.0), -(screen_height / 2.0));
	//g.translate(translate_x, translate_y);
	//g.translate(lookAtX_NM * one_px_equivalent_naut, lookAtY_NM * one_px_equivalent_naut);
	g.setColor(Color.green);

    }//end of init canvas

    public void start_program() throws FileNotFoundException, IOException, ClassNotFoundException {


	//frame.setLocationRelativeTo(null);
	//frame.setVisible(true);

	translate_x = (float) (this.getWidth() / 2.0);
	translate_y = -(float) (this.getHeight() / 2.0 - .5);

	fix_map_movement();



    }

    public void test_draw(Graphics2D g) {
	for (int i = 0; i < 10; i++) {
	    push_matrix(g);

	    pop_matrix(g);
	}//end for
    }//end of test draw

    //rabbi
    public static void paintIt() {
	gameScene.HTBParent.repaint();
    }

    //n
    @Override
    public void paint(Graphics g) {
	//super.paint(g);
	Graphics2D g2d = (Graphics2D) g;
	init_canvas(g2d);

	//<--- draw map

	if (gameScene.selectedMapIndices.size() != 0) {
	    for (int i : gameScene.selectedMapIndices) {
		FCTUMap map = worldMap.get(i);
		map.draw(g, .2f);
		// translate_x = translate_x - 223;
		// translate_y = translate_y - 57;
	    }
	    ////System.out.println(map.name);
	}
	//---> draw map




	for (Base base : gameScene.baseList) 
        {
	    Color c = g2d.getColor();
	    g2d.setColor(Color.blue);
	    //g.fillRect(flag, flag, WIDTH, flag);
	    //System.out.println("base x:" + base.getLocation().getX());

	    if (base != null) {
		//g2d.fillRect((int) (base.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut) - 3, (int) (base.getLocation().getY() * one_px_equivalent_naut) - 3, 6, 6);
                
                
                
                g2d.draw(new Rectangle2D.Double((base.getLocation().getX() * one_px_equivalent_naut) - 3, (base.getLocation().getY() * one_px_equivalent_naut) - 3, 6, 6));
		g2d.setColor(c);
                
		//customDrawString(g, base.getBaseType().getName(), new Point((int) (base.getLocation().getX() * HTB_MAIN.one_px_equivalent_naut), (int) (base.getLocation().getY() * HTB_MAIN.one_px_equivalent_naut + 4)));
	    }
	}
        for (Gbad gbad : gameScene.gbadList) 
	{

            Color c1 = g.getColor();
            g.setColor(Color.red);
            //g.fillRect(flag, flag, WIDTH, flag);
            g.fillRect((int) gbad.getLocation().getX(), (int) gbad.getLocation().getY(), 5, 5);
            g.setColor(c1);
            //customDrawString(g, gbad.getGbadType().getName(), new Point((int) gbad.getLocation().getX(), (int) gbad.getLocation().getY() + 3));
        }
	
        for (Kpi kpi : gameScene.kList) 
	{
            //kpi.draw(g2d);
            Color color = g2d.getColor();
            g2d.setColor(Color.blue);
            //g2d.fillRect((int)x-GameScene.rectSize/2, (int)y-GameScene.rectSize/2, GameScene.rectSize, GameScene.rectSize);
            g2d.draw(new Rectangle2D.Double((kpi.getLocation().getX() * one_px_equivalent_naut) - 3, (kpi.getLocation().getY() * one_px_equivalent_naut) - 3, 6, 6));

            HTB_MAIN.customDrawString((Graphics)g2d, kpi.getName(), new Point((int)(kpi.getLocation().getX() *  one_px_equivalent_naut), (int)(kpi.getLocation().getY()* one_px_equivalent_naut) - 3));

            g2d.setColor(color);
        }
	
        // before game started, we are drawing positions of radar and aircraft
	for(Radar radar : gameScene.radarList)
	{
	    double radarX = (radar.getX()*one_px_equivalent_naut);
            double radarY = (radar.getY()*one_px_equivalent_naut);
                
	    
	    radar.drawRadarRange(g2d,radarX,radarY);
	}
        if(!gameStarted)
        {
            for(Aircraft aircraft:gameScene.airCraftList)
            {
                double aircraftx = (aircraft.getAircraftState().getLocation().getX()* one_px_equivalent_naut);
                double aircrafty = (aircraft.getAircraftState().getLocation().getY()* one_px_equivalent_naut);
                
                Color color = g2d.getColor();
                g2d.setColor(Color.GREEN);

                g2d.draw(new Rectangle2D.Double(aircraftx, aircrafty, RECT_SIZE, RECT_SIZE));

                //g2d.drawRect(aircraftx, aircrafty, RECT_SIZE, RECT_SIZE);
                
            }
            
            for(Radar radar : gameScene.radarList)
	    {
                double radarX = (radar.getX()*one_px_equivalent_naut);
                double radarY = (radar.getY()*one_px_equivalent_naut);
                
                radarX -= (RECT_SIZE / 2);
                radarY -= (RECT_SIZE / 2); 
                
                Color color = g2d.getColor();
                g2d.setColor(Color.PINK);
                g2d.draw(new Rectangle2D.Double(radarX, radarY, RECT_SIZE, RECT_SIZE));
                //g2d.drawRect(radarX, radarY, RECT_SIZE, RECT_SIZE);
                customDrawString(g2d, radar.getRadarState().getRadarName(), new Point((int)radarX+10,(int)radarY));
            }
            
            for(RandomCloud cloud : gameScene.cloudSystemList) 
	    {
//                int cloudX = (int) (cloud.getLocation().getX() * one_px_equivalent_naut);
//                int cloudY = (int) (cloud.getLocation().getY() * one_px_equivalent_naut);
//                
//                Color color = g.getColor();
//                g.setColor(Color.WHITE);
//                g.fillRect(cloudX, cloudY, (int)cloud.getDimension(), (int) cloud.getDimension());
                cloud.draw(g); 
                //repaint();
                
            }
        }
        
        //
        if (flag == 1) {
            if (point != null) {
                g2d.setColor(Color.RED);

                //g.fillRect(point.x - 3, point.y - 3, 7, 7);
                g2d.draw(new Rectangle2D.Double(point.getX() - 3, point.getY() - 3, 7, 7));
                repaint();
            }
        }
        
       /*if(radarTools.iffSignal)
        {
            for(Aircraft aircraft:gameScene.airCraftList)
            {
                int aircraftx = (int)(aircraft.getAircraftState().getLocation().getX()* one_px_equivalent_naut);
                int aircrafty = (int)(aircraft.getAircraftState().getLocation().getY()* one_px_equivalent_naut) + 5;
                
                Color color = g.getColor();
                g.setColor(Color.red);
                g.drawLine(aircraftx-5, aircrafty, aircraftx+5, aircrafty);
                
            }
        }*/
         
        
        //added for measuring distance
//        if(measureButtonClick == 1 && mousemeasuretwo==2)
//        {
           
        measureHelper.draw(g);         
            
//        }
        
        //draw grid
	int grid_width = (int) (180 * 60 * one_px_equivalent_naut); //half grid width
	int grid_height = (int) (90 * 60 * one_px_equivalent_naut);
	int i = 1;

	int nauticalMile = 60;
	int x_axis = 180;
	for (i = -x_axis; i <= x_axis; i += 15) {
	    int nautEquivalentPixel = (int) ((one_px_equivalent_naut) * nauticalMile * i);
	    g2d.setColor(Color.GRAY);
	    g2d.drawLine(nautEquivalentPixel, -grid_height, nautEquivalentPixel, grid_height);
	}//end for 


	int y_axis = 90;
	for (i = -y_axis; i <= y_axis; i += 15) {
	    int nautEquivalentPixel = (int) ((one_px_equivalent_naut) * nauticalMile * i);
	    g2d.setColor(Color.GRAY);
	    //g2d.drawLine(-grid_length, i * 10, grid_length, i * 10);
	    g2d.drawLine(-grid_width, nautEquivalentPixel, grid_width, nautEquivalentPixel);
	}//end for

	g2d.setColor(Color.RED);
	//g2d.drawLine(-grid_length, 0, grid_length, 0);
	g2d.drawLine(-grid_width, 0, grid_width, 0);
	g2d.setColor(Color.GREEN);
	g2d.drawLine(0, -grid_height, 0, grid_height);


	//new grid ended by saiful abu

	// before game started, we are drawing positions of radar and aircraft
	for (Radar radar : gameScene.radarList) {
	    double radarX =  (radar.getX() * one_px_equivalent_naut);
	    double radarY = (radar.getY() * one_px_equivalent_naut);


	    radar.drawRadarRange(g2d, radarX, radarY);
	}
//	if (!gameStarted) {
//	    for (Aircraft aircraft : gameScene.airCraftList) {
//		int aircraftx = (int) (aircraft.getAircraftState().getLocation().getX() * one_px_equivalent_naut);
//		int aircrafty = (int) (aircraft.getAircraftState().getLocation().getY() * one_px_equivalent_naut);

        //added by Irteza
        if (flagDrawRadar) {
            for (Radar radar : gameScene.radarList) {
                radar.draw(g);
            }
        }
	
        if (gameStarted == false) {
            if (gameScene.airCraftList.size() != 0) {
                for (Aircraft ac : gameScene.airCraftList) {
                    ac.draw(g);
                }//end for
            }//end if
        }//end if
        //added by bikash
        if (drawHelper.drawableFigureList.size() > 0) {
            drawHelper.draw(g);
        }//end if    
        
         if(vPressed==1)     
         {             
             drawString.draw(g);             
         }
         
         //gfg


    }//end of paint           

    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {


	// TODO code application logic here
	//(new HTB_MAIN()).start_program();
        /*
	HTB_MAIN htbMain = new HTB_MAIN();
	htbMain.addMapMarker(new MapMarkerDot(0, 0));
	htbMain.start_program();
        */
	/*
	 try
	 {
	 UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
	 }catch(Exception e)
	 {
	 //System.out.println("Nimbus isn't available");
	 }
        
        
	 openingform openingForm = new openingform(HTB_MAIN.gameScene);
	 openingForm.setVisible(true);
	 * */


	int i = 0;




    }//end of main

    //n
    public static void push_matrix(Graphics2D g) {
	//throw new UnsupportedOperationException("Not yet implemented");
	affineTransform = g.getTransform();
    }//end of push matrix

    //n
    public static void pop_matrix(Graphics2D g) {
	//throw new UnsupportedOperationException("Not yet implemented");
	g.setTransform(affineTransform);
    }//end of pop matrix

    @Override
    public void actionPerformed(ActionEvent e) {

	if (e.getSource() == aircraft) {
	    ////System.out.println("aircraft");
	    ob.setVisible(true);
	    ////System.out.println("Add option selected");

        } else if (e.getSource() == utility) {
            ////System.out.println("utility");
            ut.setVisible(true);
        }else if(e.getSource() == cgi){
            if(cgiForm == null){cgiForm = new CGI();}
            cgiForm.setVisible(true);
        }
        else if (e.getSource() == exit) {
            ////System.out.println("aircraft");
            //     ob.setVisible(true);
            System.exit(0);
        } //rabbi 
        else if (e.getSource() == radarToolsMenu) {
            ////System.out.println("radar button created.");
            radarTools.setVisible(true);


	} else if (e.getSource() == openConnection) {
	    String name = gameScene.userName;



	    try {
		new FCTUClient(name, servername, this);

	    } 
            catch (Exception ex) {
		//System.out.println( "Error --> " + ex.getMessage());
	    }


	} 
        else if (e.getSource() == saveGS) {
            saveGS();
        }
        
        else if (e.getSource() == loadGS) {
            loadGS();
        }
        
        else if (e.getSource() == lookupConnection) {

            try {
                gameScene.userName = InetAddress.getLocalHost().getHostName();
            }
            catch(Exception ex) {
                
            }
	    String name = gameScene.userName;
	    String text = name + "%client";


	    try {
		new GetClientsConnection(text, servername, this);
	    } catch (Exception ex) {
		//out.println( "Error --> " + ex.getMessage());
	    }
	} // rabbi end
	else if (e.getSource() == radarToolsMenu) {
	    ////System.out.println("radar button created.");
	    radarTools.setVisible(true);


	} else if (e.getSource() == create) {
	    CreateForm createForm = new CreateForm();
	    createForm.setVisible(true);
	    ////System.out.println("create");

	} else if (e.getSource() == geofigure) {
	    ////System.out.println("figure");
	} else if (e.getSource() == gamecontrol) {
	    frameGameControl.setVisible(true);

	} else if (e.getSource() == aircraftTools) {
	    frameAircraftTools.setVisible(true);
	} else if (e.getSource() == voice) {
	    vc.setVisible(true);
	}


    }//end of method

    private void loadGS()
    {
        JFileChooser jFileChooser = new JFileChooser();
	int returnVal = jFileChooser.showOpenDialog(this);
	
	if(returnVal == JFileChooser.APPROVE_OPTION)
	{
	    File file = jFileChooser.getSelectedFile();	    
	    
	    try
	    {
		//file.createNewFile();		
		
		FileInputStream fileInputStream = new FileInputStream(file);
		ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
		this.gameScene = (GameScene)objectInputStream.readObject();
                gameScene.HTBParent = this;
		objectInputStream.close();				
		
	    }	    
	    catch(Exception ex)
	    {
		//System.out.println("from load:" + ex.toString());
	    }    
        }
    }
    private void saveGS()
    {
        JFileChooser jFileChooser = new JFileChooser();
	int returnVal = jFileChooser.showSaveDialog(this);
	
	if(returnVal == JFileChooser.APPROVE_OPTION)
	{
	    File file = jFileChooser.getSelectedFile();	    
	    
	    try
	    {
		file.createNewFile();		
		
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
		objectOutputStream.writeObject(this.gameScene);         
		
		objectOutputStream.flush();
		objectOutputStream.close();		
	    }	    
	    catch(Exception ex)
	    {
		//System.out.println("from save:" + ex.toString());
	    }    
        }
    }
    
    /**
     * @return the recordedGame
     */
    public RecordedGame getRecordedGame() {
	return recordedGame;
    }

    /**
     * @param recordedGame the recordedGame to set
     */
    public void setRecordedGame(RecordedGame recordedGame) {
	this.recordedGame = recordedGame;
    }

    /**
     * @return the listAutoLock
     */
    public List<AutoLock> getListAutoLock() {
	return listAutoLock;
    }

    /**
     * @return the listAutoLockGround
     */
    public List<AutoLockGround> getListAutoLockGround() {
	return listAutoLockGround;
    }

    //n
    
    class CustomMouseListener extends MouseMotionAdapter implements MouseListener {

	/*
	 CustomMouseListener(JFrame frame){
	 this.frame = frame;
	 }
	 * */
	//JFrame frame;
	float first_clicked_x, first_clicked_y;

	//saiful abu rr2
	@Override
	public void mouseClicked(MouseEvent e) {
	    double x = ((e.getX() - translate_x));
	    double y = (-(e.getY()) + translate_y);

	    point = new Point2D.Double(x, y);
            currentZoom = zoom;
            
                       
	    switch (lastPressedButton) {
		case ADD_AIRCRAFT:
		    new AddAircraft(gameScene, point).setVisible(true);
		    break;

		case ADD_RADAR:
		    ////System.out.println("now add radar from list");
		    new AddRadar(gameScene, point).setVisible(true);
		    break;
		case ADD_BASE:
		    AddBase b = new AddBase(gameScene, point);
		    b.setVisible(true);
		    break;
		case ADD_KPI:
		    new Addkpi(gameScene, point).setVisible(true);
		    break;
                case ADD_CLOUD :
                    new AddCloud(gameScene, point).setVisible(true);
                    break;
                    /*
                case DRAG_AIRCRAFT:
                    //DragAircraft da = new DragAircraft(gameScene, point);
                    //da.checkPoint(x,y); 
                    break;*/
		case AUTOLOCK:
		    
		    ////System.out.println("from htbmain: autolocked");
		    // here autolock is added to the first radar
		    //AutoLock autoLock = new AutoLock(radar);		    
		    /*
		    Radar radar = gameScene.radarList.get(0); 
		    
		    radar.getAutoLock().execute(point);
		    */
		    /*
		    for(Radar radar: gameScene.radarList)
		    {
			radar.getAutoLock().execute(point);
		    }  
		    */
		    
		    for(AutoLock autoLock: listAutoLock)
		    {
			autoLock.execute(point);
		    }
		    
		    break;
		case REMOVE_AUTOLOCK:
		    ////System.out.println("from htbmain: autolocked");
		    /*
		    radar = gameScene.radarList.get(0); 
		    
		    */
		    for(AutoLock autoLock: listAutoLock)
		    {
			autoLock.executeRemoveAutoLock(point);
		    }	    
		    
		    break;

		case AUTOLOCK_GROUND:
		    /*
		    Radar radar = gameScene.radarList.get(0); 
		    // here autolock is added to the first radar

		    radar.getAutoLockGround().execute(point);
		    */
		    /*
		    for(Radar radar: gameScene.radarList)
		    {
			radar.getAutoLockGround().execute(point);
		    }*/	
		    for(AutoLockGround autoLockGround :listAutoLockGround)
		    {
			autoLockGround.execute(point);
		    }
		    
		    break;
		    
		case REMOVE_AUTOLOCK_GROUND:
		    
		    for(AutoLockGround autoLockGround :listAutoLockGround)
		    {
			autoLockGround.executeRemoveAutoLockGround(point);
		    }
		    break;
		    
		case ADD_GBAD:

                    new AddGBAD(gameScene, point).setVisible(true);
                    break;
                    
                case MEASURE_TOOL:
                    //controlMeasureClick();    
                    //measureHelper.clickedPosition(point);
                    measureHelper.clickedPosition(x * one_nm_equivalent_pixel, y * one_nm_equivalent_pixel);
                    break;      
                case DRAW_TOOLS:
                    double xInNaut = x * one_nm_equivalent_pixel;
                    double yInNaut = y * one_nm_equivalent_pixel;
                    drawHelper.passPoint(xInNaut, yInNaut);
                    //System.out.println("from htb main size of draw helper " + drawHelper.drawableFigureList.size());
                    break;
		
		case ECM:
		    Aircraft aircraft = GeneralUtil.getAircraftClicked(gameScene.airCraftList, x * one_nm_equivalent_pixel, y * one_nm_equivalent_pixel);
		    
		    if(aircraft == null)
		    {
			break;
		    }
		    
		    AddECM addECM = new AddECM(aircraft,HTB_MAIN.gameScene.radarList);
		    addECM.setVisible(true);		    
		    break;
		case EPM:
		    Aircraft aircraftForEpm = GeneralUtil.getAircraftClicked(gameScene.airCraftList, x * one_nm_equivalent_pixel, y * one_nm_equivalent_pixel);
		    Radar radarForEpm = GeneralUtil.getRadarClicked(gameScene.radarList, x * one_nm_equivalent_pixel, y * one_nm_equivalent_pixel);
		    if(radarForEpm == null){
			//System.out.println("EPM window not created ,,..............");
			break;
		    }
		    AddEPM addEPM = new AddEPM(aircraftForEpm,radarForEpm );
		    addEPM.setVisible(true);	
		    //System.out.println("EPM WIndow created ... ***************** hurray");
		    break;
                case NONE:
                    JOptionPane.showMessageDialog(null, "None!");
                    checkIfAircraftCliecked();
                    break;
	    }//end of switch case button
            
            /*
             //added by bks
                    if(measureButtonClick == 1)
                    {        
                        //mousepressclik=1;
                        
                        mousemeasuretwo++;
                        measureHelper.clickedPosition(point);    
                        ////System.out.println("from htb_main when 1");
                        
                        if(mousemeasuretwo==3)
                        {
                            mousemeasuretwo=2;
                        }
                        
                    }                    
                    if(measureButtonClick == 0)
                    {                        
                        mousemeasuretwo=0;
                        
                        measureHelper.clickedPosition(null);
                        ////System.out.println("from htb_main when 0");
                    }
                    * */

/*
	    //added by bks
	    if (measureButtonClick == 1) {
		//mousepressclik=1;

		mousemeasuretwo++;
		measureHelper.clickedPosition(point);
		////System.out.println("from htb_main when 1");

		if (mousemeasuretwo == 3) {
		    mousemeasuretwo = 2;
		}

	    }
	    if (measureButtonClick == 0) {
		mousemeasuretwo = 0;

		measureHelper.clickedPosition(null);
		////System.out.println("from htb_main when 0");
	    }*/

	    repaint();
	}
        
        public void checkIfAircraftCliecked() {
            
            
        }

	@Override
	public void mouseDragged(MouseEvent e) {
	    //super.mouseDragged(e);
	    //System.out.println(e.getX() + " " + e.getY() + " " + first_clicked_x + " " + first_clicked_y);
            super.mouseDragged(e);
	    translate_x += (e.getX() - first_clicked_x);
	    translate_y -= (e.getY() - first_clicked_y);


	    first_clicked_x = e.getX();
	    first_clicked_y = e.getY();

	    //added by saiful abu
	    HTB_MAIN.this.fix_map_movement();
            
           //by bks
           int modifiers = e.getModifiers();
           if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) 
           {
            //HTB_MAIN.this.fix_map_movement();
            double x = ((e.getX() - translate_x));
	    double y = (-(e.getY()) + translate_y);

            Point2D point1;

	    point1 = new Point2D.Double(x, y);
            
            //System.out.println("Right button pressed.");
            DragAircraft da = new DragAircraft(gameScene, point1);
           }
           
           //end by bks

	    myframe.repaint();
	}

	@Override
	public void mousePressed(MouseEvent e) {
	    //throw new UnsupportedOperationException("Not supported yet.");
	    first_clicked_x = e.getX();
	    first_clicked_y = e.getY();

	}

	public void mouseMoved(MouseEvent me) {

	    int x = (int) ((me.getX() - translate_x));
	    //int y = (int) (-(me.getY()) - translate_y);
            int y = (int) (-(me.getY()) + translate_y);


	    //point = new Point(x, y);
	    //measureHelper.updateCursorPosition(point);
            measureHelper.updateCursorPosition(x * one_nm_equivalent_pixel, y * one_nm_equivalent_pixel);
            
     
	    repaint();
            
	}//end of mouse moved

	@Override
	public void mouseReleased(MouseEvent e) {
	    //throw new UnsupportedOperationException("Not supported yet.");
	    first_clicked_x = e.getX();
	    first_clicked_y = e.getY();           
  
	}

	//}
	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}
    }//end of custom mouse listener

    public void drawMapClick()// click of map button from aircraft
    {
	flag = 1;
	repaint();
    }

    public void controlMeasureClick()// click of utility measure button
    {
        //System.out.println("didnt clicked on measure button");
	if (measureButtonClick == 0) {
	    measureButtonClick = 1;
	} else if (measureButtonClick == 1) {
	    measureButtonClick = 0;
	}
	//repaint();
    }

    public void zoom_in() {
	//if (current_zoom_level == min_zoom) {
	if (current_zoom_level == max_zoom) {
	    return;
	}
	//current_zoom_level--;
	current_zoom_level++;
	set_nm_equivalent_pixel();
	//repaint();
    }//end of zoom in

    public void zoom_out() {

	if (current_zoom_level == min_zoom) {
	    return;
	}
	//current_zoom_level++;
	current_zoom_level--;
	set_nm_equivalent_pixel();
	// repaint();
    }//end of zoom in

    public void set_nm_equivalent_pixel() {
	int look_at_point_x = (int) (getWidth() / 2 - translate_x);
	int look_at_point_y = (int) (-(getHeight() / 2) - translate_y);
	float look_at_point_old_nm_system_x = look_at_point_x * one_nm_equivalent_pixel;
	float look_at_point_old_nm_system_y = look_at_point_y * one_nm_equivalent_pixel;

	one_nm_equivalent_pixel = (float) (Math.pow(2, current_zoom_level) / screen_width);
	one_px_equivalent_naut = (float) (screen_width / Math.pow(2, current_zoom_level));

	one_nm_equivalent_pixel = (float) ((float) zoomMap.get(current_zoom_level) / screen_width); //casting to float in fear of integer division
	one_px_equivalent_naut = (float) ((float) screen_width / zoomMap.get(current_zoom_level));

	int old_look_at_point_x_in_new_pixel_system = (int) (look_at_point_old_nm_system_x * one_px_equivalent_naut);
	int old_look_at_point_y_in_new_pixel_system = (int) (look_at_point_old_nm_system_y * one_px_equivalent_naut);

	//old look at point should be shifte to mid point
	translate_x += (look_at_point_x - old_look_at_point_x_in_new_pixel_system);
	translate_y += (look_at_point_y - old_look_at_point_y_in_new_pixel_system);

	repaint();

    }

    public static void customDrawString(Graphics g, String str, Point point) {
	Graphics2D graphics2d = (Graphics2D) g;

	push_matrix(graphics2d);

	graphics2d.scale(1, -1);

	graphics2d.drawString(str, (float)(point.getX() + 5), (float)-((point.getY() + 5)));

	pop_matrix(graphics2d);


    }//end of customDrawString

    public static void customDrawString2(Graphics g, String str, Point point) {
	Graphics2D graphics2d = (Graphics2D) g;

	push_matrix(graphics2d);

	graphics2d.scale(1, -1);

	graphics2d.drawString(str, (point.x + 5), -(point.y + 25));

	pop_matrix(graphics2d);


    }//end of customDrawString

    public static void customDrawString3(Graphics g, String str, Point point) {
	Graphics2D graphics2d = (Graphics2D) g;
	push_matrix(graphics2d);
	graphics2d.scale(1, -1);
	graphics2d.drawString(str, (point.x + 5), -(point.y + 45));
	pop_matrix(graphics2d);


    }//end of customDrawString

    public void fix_map_movement() {
	Coordinate coOrdinate = new Coordinate(0, 0);
	Point p = this.getMapPosition(coOrdinate, false);
	translate_x = p.x;
	translate_y = p.y;

	one_px_equivalent_naut = (float) this.getOnePixEquivalentNM();
	one_nm_equivalent_pixel = 1 / one_px_equivalent_naut;
    }//end of method

    public class CustomWheelListener implements MouseWheelListener {

	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
	    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
	    HTB_MAIN.this.fix_map_movement();
	    HTB_MAIN.paintIt();
	}
    }//end of class my wheel listener
    public static Timer CGITimer = new Timer("cgi timer");
    
    //by bikash
   public DrawHelper drawHelper = new DrawHelper();
    
}//end of class HTB_Main
